﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Syndication;
using RecruitmentAgency.Models.DataTypes;
using System.Web;

namespace RecruitmentAgency.Models.DataProviders
{
    /// <summary>
    /// Provides database access for job data
    /// </summary>
    public class JobDataProvider : BaseDataProvider, IJobDataProvider
    {
        private List<string> Cache(string cacheName)
        {
            if (HttpRuntime.Cache[cacheName] != null) return (List<string>)HttpRuntime.Cache[cacheName];
            return null;
        }

        #region Get Drop down list content

        /// <summary>
        /// Gets unique job titles from the database
        /// </summary>
        /// <returns>A list of unique job titles</returns>
        public List<string> GetUniqueJobTitles()
        {
            if (Cache("jobTitles") != null) return Cache("jobTitles");
            else
            {
                List<string> jobTitles = new List<string>();
                try
                {
                    foreach (up_GetUniqueSkillNamesResult result in DataContext.up_GetUniqueSkillNames())
                    {
                        jobTitles.Add(result.SkillName);
                    }
                }
                catch (Exception ex)
                {
                    DataProvider.HandleException(ex);
                }
                if (jobTitles.Count > 0) jobTitles.Sort();
                HttpRuntime.Cache["jobTitles"] = jobTitles;
                return jobTitles;
            }
        }

        /// <summary>
        /// Gets unique job sectors from the database
        /// </summary>
        /// <returns>A list of unique job sectors</returns>
        public List<string> GetUniqueJobSectors()
        {
            if (Cache("jobSectors") != null) return Cache("jobSectors");
            else
            {
                List<string> jobSectors = new List<string>();
                try
                {
                    foreach (up_GetUniqueSectorJobsResult result in DataContext.up_GetUniqueSectorJobs())
                    {
                        jobSectors.Add(result.SectorName);
                    }
                }
                catch (Exception ex)
                {
                    DataProvider.HandleException(ex);
                }
                if (jobSectors.Count > 0) jobSectors.Sort();
                HttpRuntime.Cache["jobSectors"] = jobSectors;
                return jobSectors;
            }
        }

        #endregion

        /// <summary>
        /// Gets the job search results and paging data
        /// </summary>
        /// <param name="pageSize">The number of rows of results to a page</param>
        /// <param name="pageNumber">The number of the page of results to return</param>
        /// <param name="jobTitle">The job title to search for</param>
        /// <param name="jobDescription">The job description to search for</param>
        /// <param name="closingDate">The closing date to search for</param>
        /// <param name="jobSector">The job sector to search for</param>
        /// <returns>A JobSearchData instance that holds the Job results and paging data</returns>
        public JobSearchData SearchJobs(int pageSize, int pageNumber, string jobTitle, string jobDescription, string closingDate, string jobSector)
        {
            JobSearchData searchData = new JobSearchData {PageSize = pageSize, PageNumber = pageNumber};
            try
            {
                DateTime? nullableDate = null;
                if (!string.IsNullOrEmpty(closingDate)) nullableDate = DateTime.Parse(closingDate);
                foreach (up_SearchJobsResult result in DataContext.up_SearchJobs(pageSize, pageNumber, jobTitle, jobDescription, nullableDate, jobSector))
                {
                    Job job = new Job
                    {
                        JobId = (int) result.JobId,
                        JobTitle = result.JobTitle,
                        ClosingDate = ((DateTime)result.ClosingDate).ToLongDateString(),
                        JobSector = result.JobSector
                    };
                    searchData.Results.Add(job);
                    searchData.TotalResultCount = (int)result.TotalResultCount;
                }
            }
            catch (Exception ex)
            {
                DataProvider.HandleException(ex);
            }
            return searchData;
        }

        /// <summary>
        /// Gets the Job instance that relates to the provided jobId
        /// </summary>
        /// <param name="jobId">The ID number of the job whose personal details are required</param>
        /// <returns>A PersonalDetail instance</returns>
        public Job GetJob(int jobId)
        {
            Job job = new Job();
            try
            {
                List<up_GetJobResult> results = DataContext.up_GetJob(jobId).ToList();
                if (results.Count > 0)
                {
                    up_GetJobResult result = results[0];
                    job.JobId = result.JobId;
                    job.JobTitle = result.JobTitle;
                    job.JobDescription = result.JobDescription;
                    job.JobSector = result.JobSector;
                    job.JobCreated = ((DateTime)result.DateCreated).ToLongDateString();
                    job.ClosingDate = ((DateTime)result.ClosingDate).ToLongDateString();
                    job.JobProviderId = result.JobProviderId;
                    job.JobProviderName = result.JobProviderName;
                }
            }
            catch (Exception ex)
            {
                DataProvider.HandleException(ex);
            }
            return job;
        }

        /// <summary>
        /// Delete a job from the database
        /// </summary>
        /// <param name="jobId">The id of the job to delete</param>
        public void DeleteJob(int jobId)
        {
            try
            {
                DataContext.up_DeleteJob(jobId);
            }
            catch (Exception ex)
            {
                DataProvider.HandleException(ex);
            }
        }

        /// <summary>
        /// Add a job to the database
        /// </summary>
        /// <param name="job">The job instance containing all the data relevant to the job</param>
        public void AddJob(Job job)
        {
            try
            {
                DataContext.up_AddJob(job.JobTitle, job.JobDescription, DateTime.Parse(job.ClosingDate), job.JobSector, job.JobProviderId);
            }
            catch (Exception ex)
            {
                DataProvider.HandleException(ex);
            }
        }

        /// <summary>
        /// Update a job in the databse
        /// </summary>
        /// <param name="job">The job instance containing all the job details</param>
        public void UpdateJob(Job job)
        {
            try
            {
                DataContext.up_UpdateJob(job.JobId, job.JobTitle, job.JobDescription, DateTime.Parse(job.ClosingDate), job.JobSector);
            }
            catch (Exception ex)
            {
                DataProvider.HandleException(ex);    
            }
        }
       
        /// <summary>
        /// Gets a System.ServiceModel.Syndication.SyndicationFeed full of Job data
        /// </summary>
        /// <param name="homePageUri">The URI of the page to go to when the user clicks the RSS feed title link</param>
        /// <returns>A System.ServiceModel.Syndication.SyndicationFeed full of Job data</returns>
        public SyndicationFeed GetJobRssFeed(string homePageUri)
        {
            List<SyndicationItem> rssItems = new List<SyndicationItem>();
            try
            {
                // create RSS items
                foreach (up_GetJobDataForRssResult result in DataContext.up_GetJobDataForRss())
                {
                    SyndicationItem rssItem = new SyndicationItem();
                    rssItem.Id = "ConnectionsJobPosition" + result.JobId;
                    rssItem.Categories.Add(new SyndicationCategory(result.SectorName + " sector"));
                    rssItem.LastUpdatedTime = result.DateCreated;
                    rssItem.Links.Add(new SyndicationLink(new Uri(homePageUri + "ViewJob/" + result.JobId)));
                    rssItem.PublishDate = DateTime.Now;
                    string summary = result.JobDescription + "<br />" + "Closing date: " + result.ClosingDate.ToLongDateString();
                    rssItem.Summary = SyndicationContent.CreateHtmlContent(summary);
                    rssItem.Title = SyndicationContent.CreatePlaintextContent(result.JobTitle);
                    rssItems.Add(rssItem);
                }
            }
            catch (Exception ex)
            {
                DataProvider.HandleException(ex);
            }
            // create RSS feed
            SyndicationFeed rssFeed = new SyndicationFeed(rssItems);
            rssFeed.Description = new TextSyndicationContent("You can click on the links to view the full job details at the Connections website.");
            rssFeed.Id = "ConnectionsJobPositions1";
            rssFeed.LastUpdatedTime = DateTime.Now;
            rssFeed.Links.Add(new SyndicationLink(new Uri(homePageUri)));
            rssFeed.Title = new TextSyndicationContent("Connections job positions");
            return rssFeed;
        }
    }
}
